import { Component, createRef, RefObject, flushSync } from 'react'
import { defaultProps, defaultState } from '../types/baseType.ts'

type Props = defaultProps
type State = defaultState & {
	count: number
}

class AboutThis extends Component<Props, State> {
	private btnRef: RefObject<HTMLInputElement> | undefined

	constructor(props: Props) {
		super(props)
		this.state = {
			count: 0,
		}
		/* 考点1、非箭头函数需要手动绑定 this */
		// this.handleClick = this.handleClick.bind(this)
		this.btnRef = createRef()
	}

	componentDidMount() {
		// componentDidMount 会执行 2 次
		console.log('this.btnRef', this.btnRef)
		/* 考点2、设置 dom 事件时。回调函数最好传具名函数，防止事件添加两次以及方便清除事件。 */
		// 因为 componentDidMount 声明周期执行两次，导致设置监听事件时也会设置两次
		// 如果监听事件回调函数是个匿名函数，那么监听事件设置两次时，回调会设置两次一摸一样的回调
		// 如果监听事件回调函数是个具名函数，那么监听事件设置两次时，回调会设置两次，但是因为 函数名相同 实际上后面的函数会覆盖前面的（事件内部会去重）
		// this.btnRef?.current?.addEventListener('click', () => {
		//     this.handleClick1()
		// })
		// document.getElementById('btn')?.addEventListener('click', () => {
		//     this.handleClick1()
		// })
		this.btnRef?.current?.addEventListener('click', this.handleClick1)
	}

	handleClick() {
		// https://juejin.cn/post/6844904150589767688
		console.log('this 不手动绑定，默认 undefined', this)
	}

	handleClick1 = () => {
		this.setState((preState) => {
			return {
				count: preState.count + 1,
			}
		})
	}

	handleClick2 = () => {
		// 考点3、同步更新 state
		flushSync(() => {
			this.setState({
				count: this.state.count + 1,
			})
		})
	}

	componentWillUnmount() {
		this.btnRef?.current?.removeEventListener('click', this.handleClick1)
	}

	render() {
		const { count } = this.state
		console.log('count', count)
		return (
			<div>
				<h3>AboutThis</h3>
				<p>count {count}</p>
				{/* 考点4、禁止在 jsx 中设置具体函数，只传函数名，有利用性能优化 */}
				<input
					type="button"
					value="不绑定this点击"
					onClick={this.handleClick}
				/>
				<input
					type="button"
					value="箭头函数点击"
					onClick={this.handleClick1}
				/>
				<input
					type="button"
					value="同步执行"
					onClick={this.handleClick2}
				/>
				<input
					type="button"
					value="原生事件点击"
					ref={this.btnRef}
					id="btn"
				/>
				<hr />
			</div>
		)
	}
}

export default AboutThis
